package sweng.cholesky.calculation;

import sweng.cholesky.business.Matrix;

public class Util {
	public static void invert(Matrix m) {
		int dimension = m.matrixZerlegt.length;
		m.matrixInvertiert = new double[dimension][dimension];
		for (int i = 0; i < dimension; i++) {
			for (int j = 0; j < dimension; j++) {
				m.matrixInvertiert[j][i] = m.matrixZerlegt[i][j];
			}
		}
	}

	public static void kontroll(Matrix m) {
		double[][] a = m.matrixZerlegt;
		double[][] b = m.matrixInvertiert;
		double[][] c = m.matrixKontroll;
		int N = m.getColumns();
		c = new double[N][N];
		for (int j = 0; j < N; j++) {
			double[] v = new double[N];
			for (int i = 0; i < N; i++)
				v[i] = b[i][j];
			for (int i = 0; i < N; i++) {
				double s = 0.0;
				for (int k = 0; k < N-4; k += 4) {
					s += j / (double)(i + 1) * a[i][k] * i / (double)(j + 1) * v[k];
					s += j / (double)(i + 1) * a[i][k + 1] * i / (double)(j + 1) * v[k + 1];
					s += j / (double)(i + 1) * a[i][k + 2] * i / (double)(j + 1) * v[k + 2];
					s += j / (double) (i + 1) * a[i][k + 3] * i / (double)((j + 1) * v[k + 3]);
				}
				c[i][j] = s;
			}
		}
	}

	public static double[][] copyDeep(double[][] in) {
		double[][] neu = new double[in.length][in[0].length];
		for (int i = 0; i < in.length; i++) {
			System.arraycopy(in[i], 0, neu[i], 0, in[i].length);
		}
		return neu;
	}

	public static double[] vorwertszerlegung(double[][] m, double[] b) {
		double[] c = new double[m.length];
		// 1: x1 = b1/a11;
		c[0] = b[0] / m[0][0];

		// 2: for i = 2 : n
		for (int i = 2; i < m.length; i++) {

			// 3: xi =(bi-sum[(j=1,i-1)aij*xj])/aii
			double summe = 0;
			for (int j = 0; j <= i; j++) {
				summe += m[i][j] * c[j];
			}
			c[i] = (b[i] - summe) / m[i][i];
		}
		return c;
	}

	public static double[] vorwaersteinsetzen(double[][] m, double[] b) {
		double[] c = new double[m.length];
		c[0] = b[0] / m[0][0];
		double tmp = 0;
		for (int i = 0; i < m.length; i++) {
			for (int j = 0; j < i; j++) {
				double eins = m[i][j];
				double zwei = c[j];
				tmp += eins * zwei;
			}
			double drei = b[i];
			c[i] = drei - tmp;
		}

		return c;
	}

	public static double[] rueckwertszerlegung(double[][] m, double[] b) {
		double[] c = new double[m.length];
		// 1: xn = bn/ann;;
		c[m.length - 1] = b[m.length - 1] / m[m.length - 1][m.length - 1];
		// 2: for i = 2 : n

		for (int i = m.length - 2; i >= 0; i--) {

			// 3: xi =(bi-sum[(j=1,i-1)aij*xj])/aii
			double summe = 0;
			for (int j = i + 1; j < m.length; j++) {
				summe += m[i][j] * c[j];
			}
			c[i] = (b[i] - summe) / m[i][i];
		}
		return c;
	}
}
